package com.rwy.web.controller;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.HttpStatus;
import org.hibernate.validator.internal.util.privilegedactions.GetConstraintValidatorList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.rwy.dto.device.EmployeeDTO;
import com.rwy.service.HandleFaultDeviceService;
import com.rwy.util.CommonController;
import com.rwy.util.JsonObject;
import com.rwy.util.MemberDTO;
import com.rwy.util.ObjectUtil;
import com.rwy.util.RWYException;
import com.rwy.util.StringUtil;
import com.rwy.util.constant.AppTokenEnum;
import com.rwy.util.constant.CacheKeyEnum;
import com.rwy.util.constant.CacheValueKeyEnum;
import com.rwy.web.filter.authorize.AuthorizeRespDTO;
import com.rwy.web.filter.authorize.JSSDKTicketDTO;
import com.tool.http.httpclient.HttpClientUtil;
import com.tool.util.http.common.HttpConfig;

import lombok.extern.log4j.Log4j;

@RestController
@RequestMapping("/user")
@Log4j
public class LoginController extends CommonController {
	
	@Autowired
	HandleFaultDeviceService deviceService;
	
	/*本地login 视图 调试使用 */
	//@RequestMapping(value="/fault/authorize")
	public ModelAndView unitEmployeeLogin(HttpServletRequest request) throws Exception {
		String url ="";
		ModelAndView mv = getModelAndView();
		String mobile = "18819300173";
		AuthorizeRespDTO tokenDto = getFaultAccessToken();
		JSSDKTicketDTO ticket = getJSSDKTicket(tokenDto.getAccess_token());
		if (ObjectUtil.isEmpty(ticket)) {
			log.error("user login error, get js sdk ticket error !");
			log.error("获取数据失败,请尝试重新登录!");
			throw RWYException.create(101);
		}
		
	
		String key = StringUtil.getUUID();
		url += api_domain + "/"+login_fault_redirect_url;
		if (!StringUtil.isEmpty(request.getQueryString())) {
			url += "?"+ request.getQueryString();
		}
		log.info(url);
		EmployeeDTO user = deviceService.getEmployMesByMobile(mobile);
		addUserCacheElement(key, user);
		Map<String, String> resp = getSign(ticket.getTicket(), url);
		log.info("resp" + resp);
		resp.put(common_token, key);
		mv.addObject(common_token, key);
		mv.addObject("ticket", JSON.toJSONString(resp));
		mv.addObject("fault_login_url", fault_login_url);
		mv.addObject("fault_api_domain", api_domain);
		mv.setViewName("fault_device");
		return mv;
	}
	
	/*public JsonObject getSignature() {
		
	}*/
	
	/** 本地json 登录 数据 */
	//@RequestMapping(value="/fault/authorize", produces= "application/json; charset=UTF-8")
	public JsonObject temp_login(Integer login_type, HttpServletRequest request)  throws Exception {
		AuthorizeRespDTO tokenDto = getCommonAccessToken();
		String url = "";
		JSSDKTicketDTO ticket = getJSSDKTicket(tokenDto.getAccess_token());
		if (ObjectUtil.isEmpty(ticket)) {
			log.error("user login error, get js sdk ticket error !");
			log.error("获取数据失败,请尝试重新登录!");
			throw RWYException.create(101);
		}
		url += api_domain + "/"+login_fault_redirect_url;
		if (!StringUtil.isEmpty(request.getQueryString())) {
			url += "?"+ request.getQueryString();
		}
		
		JsonObject json = JsonObject.getInstance();
		String mobile = "18819300173";
		String key = StringUtil.getUUID();
		EmployeeDTO user = deviceService.getEmployMesByMobile(mobile);
		addUserCacheElement(key, user);
		log.info(AppTokenEnum.common_app_token.getToken_key());
		Map<String, String> resp = getSign(ticket.getTicket(), url);
		resp.put(common_token, key);
		json.setData(resp);
		setJsonMesasge(json);
		return json;
	}
	
	/** 正式故障处理 登录接口 */
	@RequestMapping(value="/fault/authorize")
	public ModelAndView employeeLogin(String code, HttpServletRequest request) {
		ModelAndView mv = new ModelAndView();
		String erroMsg = "";
		String url = "";
		AuthorizeRespDTO tokenDto = null;
		JSSDKTicketDTO ticket = null;
		try {
			// 获取员工code, 然后
			if (StringUtil.isEmpty(code)) {
				log.error("get user code fail ..!");
				erroMsg = "用户授权失败请重新请求!";
				throw RWYException.create(HttpStatus.SC_UNAUTHORIZED);
			}
			
			tokenDto = getFaultAccessToken();
			if (ObjectUtil.isEmpty(tokenDto)) {
				erroMsg = "用户授权失败请重新请求!";
				throw RWYException.create(HttpStatus.SC_UNAUTHORIZED);
			}
			// 获取成员信息
			String userInfo = HttpClientUtil.get(HttpConfig.custom().url(login_get_user_info + "?access_token=" + tokenDto.getAccess_token() + "&code=" + code));
			AuthorizeRespDTO user = JSON.parseObject(userInfo, AuthorizeRespDTO.class);
			if (ObjectUtil.isEmpty(user) || StringUtil.isEmpty(user.getUserId())) {
				log.error("get user info userid fail ..." + userInfo);
				erroMsg = "你没有该应用访问权限,请联系管理员!";
				throw RWYException.create(HttpStatus.SC_UNAUTHORIZED);
			}
		
			//获取员工信息
			String mes = HttpClientUtil.get(HttpConfig.custom().url(get_member_mesage_url+"?access_token="+tokenDto.getAccess_token()+"&userid="+user.getUserId()));
			MemberDTO member = JSON.parseObject(mes, MemberDTO.class);
			if(StringUtil.isEmpty(mes)|| ObjectUtil.isEmpty(member) ||StringUtil.isEmpty(member.getMobile())){
				log.error("get member message fail ... !" + mes);
				erroMsg = "管理员没有授权用户手机号, 请联系管理员!";
				throw RWYException.create(101);
			}
			//test login  mobile 
			EmployeeDTO employee = deviceService.getEmployMesByMobile(member.getMobile());
			if (ObjectUtil.isEmpty(employee) || null == employee.getEmployeeID()) {
				log.error("user unAuthorize not has businessPartner role !");
				erroMsg = "您没有权限访问故障处理,请向管理员申请线下员工权限!";
				throw RWYException.create(101);
			} 
			
			ticket = getJSSDKTicket(tokenDto.getAccess_token());
			if (ObjectUtil.isEmpty(ticket)) {
				log.error("user login error, get js sdk ticket error !");
				erroMsg = "获取票据失败,请尝试重新登录!";
				throw RWYException.create(101);
			}
			url += api_domain + "/"+login_fault_redirect_url;
			if (!StringUtil.isEmpty(request.getQueryString())) {
				url += "?"+ request.getQueryString();
			}
			log.info(url);
			String key = StringUtil.getUUID();
			addUserCacheElement(key, employee);
			Map<String, String> resp = getSign(ticket.getTicket(), url);
			resp.put(common_token, key);
		
			mv.addObject(AppTokenEnum.common_app_token.getToken_key(), key);
			mv.addObject("ticket", JSON.toJSONString(resp));
			mv.addObject("fault_login_url", fault_login_url);
			mv.addObject("fault_api_domain", api_domain);
			mv.setViewName("fault_device");
			
		} catch (Exception e) {
			mv.setViewName("auto");
			log.error(e.getMessage());
			if (e instanceof RWYException) {
				  mv.addObject("msg", erroMsg);
			}else {
				mv.addObject("msg", "出错了,请重新请求或联系管理员!");
				//throw e;
			}
		}
		return mv;
	}
	
	

	
	private JSSDKTicketDTO getJSSDKTicket(String accessToken) throws Exception {
		JSSDKTicketDTO ticket = getCache(CacheKeyEnum.access_token.getKey(), CacheValueKeyEnum.js_sdk_ticket_key.getKey(), JSSDKTicketDTO.class);
		if (ObjectUtil.isEmpty(ticket)) {
			String ticketInfo = HttpClientUtil.get(HttpConfig.custom().url(get_jssdk_ticket + accessToken));
			ticket = JSON.parseObject(ticketInfo, JSSDKTicketDTO.class);
		
			if (ObjectUtil.isEmpty(ticket) || 0 != ticket.getErrcode() ||  StringUtil.isEmpty(ticket.getTicket())) {
				ticket = null;
			    log.error("get js sdk ticket fail .." + ticketInfo);
			} else {
				addCache(CacheKeyEnum.access_token.getKey(), CacheValueKeyEnum.js_sdk_ticket_key.getKey(), ticket);
			}
		}
		
		return ticket;
	}
	
	
	public static Map<String, String> getSign(String jsapi_ticket, String url) {  
        Map<String, String> ret = new HashMap<String, String>();  
        String nonce_str = create_nonce_str();  
        String timestamp = create_timestamp();  
        String string1;  
        String signature = "";  
  
        //注意这里参数名必须全部小写，且必须有序  
        string1 = "jsapi_ticket=" + jsapi_ticket +  
                  "&noncestr=" + nonce_str +  
                  "&timestamp=" + timestamp +  
                  "&url=" + url;  
       log.info("Sign string1:"+string1);  
  
        try  
        {  
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");  
            crypt.reset();  
            crypt.update(string1.getBytes("UTF-8"));  
            signature = byteToHex(crypt.digest());  
            System.out.println("Sign signature:"+signature);  
              
        }  
        catch (NoSuchAlgorithmException e)  
        {  
            e.printStackTrace();  
        }  
        catch (UnsupportedEncodingException e)  
        {  
            e.printStackTrace();  
        }  
  
        ret.put("url", url);  
        ret.put("jsapi_ticket", jsapi_ticket);  
        ret.put("nonceStr", nonce_str);  
        ret.put("timestamp", timestamp);  
        ret.put("signature", signature);  
  
        return ret;  
    }  
  
    private static String byteToHex(final byte[] hash) {  
        Formatter formatter = new Formatter();  
        for (byte b : hash)  
        {  
            formatter.format("%02x", b);  
        }  
        String result = formatter.toString();  
        formatter.close();  
        return result;  
    }  
  
    private static String create_nonce_str() {  
        return UUID.randomUUID().toString();  
    }  
  
    private static String create_timestamp() {  
        return Long.toString(System.currentTimeMillis() / 1000);  
    }  
	
}
